package com.haizhi.crm.biz.query;

import com.haizhi.crm.biz.dao.FavouriteDao;
import com.haizhi.crm.biz.dao.VisitRecordDao;
import com.haizhi.crm.biz.model.UserModuleDetailVo;
import com.haizhi.crm.biz.model.UserModuleReqDto;
import com.haizhi.crm.biz.model.VisitRecordDo;
import com.haizhi.crm.common.constant.CrmSchema;
import com.haizhi.crm.common.json.JSONUtils;
import com.haizhi.crm.common.util.CommonUtils;
import com.haizhi.crm.common.util.DateUtils;
import com.haizhi.crm.common.util.Getter;
import com.haizhi.crm.search.builder.SearchQoBuilder;
import com.haizhi.crm.search.service.SearchService;
import com.haizhi.crm.sys.auth.dao.UserDao;
import com.haizhi.crm.sys.auth.model.UserDo;
import com.haizhi.crm.sys.configure.model.UserModuleSettingVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by wangshan on 2018/6/19.
 */
@Service
public class VisiteQueryModelImpl extends AbstractQuery implements QueryModel {

    @Autowired
    private QueryEngine queryEngine;

    @Autowired
    private VisitRecordDao visitRecordDao;
    @Autowired
    private SearchService searchService;
    @Autowired
    private UserDao userDao;
    @Autowired
    private FavouriteDao favouriteDao;

    @PostConstruct
    public void init() {
        queryEngine.register("tv_visit_record", this);
    }

    @Override
    public UserModuleDetailVo query(UserModuleSettingVo userModuleSettingVo) {
        Long userId = CommonUtils.getUserID();
        UserModuleReqDto userModuleReqDto = parse(userModuleSettingVo);
        List<String> companyKeys = getSourceCustomer(userModuleReqDto.getSettings(), CrmSchema.VISIT_RECORD, userId);
        if (companyKeys.size() == 0) {
            return UserModuleDetailVo.builder().datas(new ArrayList<>()).settings(userModuleReqDto.getTHeads())
                    .title(userModuleReqDto.getTitle()).userModuleId(userModuleSettingVo.getUserModuleId()).build();
        }
        int pageSize = userModuleReqDto.getPageSize();
        String[] keys = companyKeys.toArray(new String[]{});
        List<VisitRecordDo> visits = visitRecordDao.findBy(keys, new PageRequest(0, pageSize, Sort.Direction.DESC, "visitTimeStart" ));
        List<Map<String, Object>> visitMaps = visits.stream().map(n -> JSONUtils.toMap(n)).collect(Collectors.toList());

        List<Object> datas = new LinkedList<>();
        buildData(userModuleReqDto, visitMaps, datas);
        return UserModuleDetailVo.builder().datas(datas).settings(userModuleReqDto.getTHeads())
                .title(userModuleReqDto.getTitle()).userModuleId(userModuleSettingVo.getUserModuleId()).build();
    }

    private void buildData(UserModuleReqDto userModuleReqDto, List<Map<String, Object>> visitMaps, List<Object> datas) {
        for (Map<String, Object> obj : visitMaps) {
            Map<String, Object> data = new LinkedHashMap<>();
            for (String field : userModuleReqDto.getFields()) {
                if ("visitTimeStart".equals(field)) {
                    data.put(field, DateUtils.formatLocal(Long.parseLong(Getter.get(field, obj))));
                } else if ("customer".equals(field)) {
                    buildCustomer(obj, data, field);
                } else if ("manager".equals(field)) {
                    UserDo userDo = userDao.findOne(Long.parseLong(Getter.get("userId", obj)));
                    data.put(field, userDo.getName());
                } else {
                    data.put(field, obj.getOrDefault(field, "" ));
                }
            }

            String objectKey = Getter.get("objectKey", obj);
            data.put("object_key", objectKey);
            int favouriteCount = favouriteDao.findFavouriteCount(CommonUtils.getUserID(), CrmSchema.VISIT_RECORD, objectKey);
            data.put("favorited", favouriteCount >= 1 ? true : false);
            datas.add(data);
        }
    }

    private void buildCustomer(Map<String, Object> obj, Map<String, Object> data, String field) {
        String customerKey = Getter.get("customerKey", obj);
        SearchQoBuilder searchQoBuilder = new SearchQoBuilder();
        searchQoBuilder.setGraph(CrmSchema.CRM);
        searchQoBuilder.addSchemas(CrmSchema.COMPANY);
        searchQoBuilder.addTermFilter("object_key", customerKey);
        Object company = searchService.search(searchQoBuilder.get()).getSearchResp().getData();
        Map<String, Object> companyMap = JSONUtils.toMap(company);
        Map<String, Object> customerMap = new LinkedHashMap<>();
        customerMap.put("objectKey", Getter.get("object_key", companyMap));
        customerMap.put("name", Getter.get("name", companyMap));
        List<Map<String, Object>> customerList = new ArrayList<>();
        customerList.add(customerMap);
        data.put(field, customerList);
    }
}
